<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.18"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Epigraph: Main Page</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="logo_small.png"/></td>
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">Epigraph
   </div>
   <div id="projectbrief">Convex Optimization in C++</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.18 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="PageDoc"><div class="header">
  <div class="headertitle">
<div class="title">Epigraph Documentation</div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p align="center"><a class="anchor" id="md_README"></a></p>
<p><img src="img/logo.png" alt="" class="inline"/> </p>
<p align="center"></p>
<p><a href="https://shields.io/"><img src="https://img.shields.io/badge/Version-0.3.3-orange.svg" alt="" style="pointer-events: none;" class="inline"/></a> <a href="https://shields.io/"><img src="https://img.shields.io/badge/Status-Beta-orange.svg" alt="" style="pointer-events: none;" class="inline"/></a> <a href="https://shields.io/"><img src="https://img.shields.io/badge/Maintained%3F-yes-green.svg" alt="" style="pointer-events: none;" class="inline"/></a> <a href="https://github.com/EmbersArc/Epigraph/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="" style="pointer-events: none;" class="inline"/></a> <a href="https://travis-ci.org/github/EmbersArc/Epigraph"><img src="https://api.travis-ci.org/EmbersArc/Epigraph.svg?branch=master" alt="" style="pointer-events: none;" class="inline"/></a> <a href="https://codecov.io/gh/EmbersArc/Epigraph"><img src="https://codecov.io/gh/EmbersArc/Epigraph/branch/master/graph/badge.svg" alt="" style="pointer-events: none;" class="inline"/></a> </p>
<p>Epigraph is a modern C++ interface to formulate and solve linear, quadratic and second order cone problems. It makes use of Eigen types and operator overloading for straightforward problem formulation.</p>
<h2><a class="anchor" id="autotoc_md0"></a>
Features</h2>
<ul>
<li>Flexible and intuitive way to formulate LPs, QPs and SOCPs</li>
<li>Dynamic parameters that can be changed without re-formulating the problem</li>
<li>Automatically clean up the problem and remove unused variables</li>
<li>Print the problem formulation and solver data for inspection</li>
</ul>
<h2><a class="anchor" id="autotoc_md1"></a>
Dependencies</h2>
<ul>
<li><a href="http://eigen.tuxfamily.org">Eigen</a></li>
<li><a href="https://github.com/fmtlib/fmt">fmt</a> (optional, only for tests)</li>
</ul>
<h2><a class="anchor" id="autotoc_md2"></a>
Supported Solvers</h2>
<p>The solvers are included as submodules for convenience. Note that some solvers have more restrictive licenses which automatically override the Epigraph license when activated. Pass the listed argument to cmake during configuration to enable the solvers.</p>
<h3><a class="anchor" id="autotoc_md3"></a>
QP</h3>
<ul>
<li><a href="https://github.com/oxfordcontrol/osqp">OSQP</a> <code>-DENABLE_OSQP=TRUE</code>. Apache-2.0 License.</li>
</ul>
<h3><a class="anchor" id="autotoc_md4"></a>
SOCP</h3>
<ul>
<li><a href="https://github.com/embotech/ecos">ECOS</a> <code>-DENABLE_ECOS=TRUE</code>. GPLv3 License.</li>
<li><a href="https://github.com/embersarc/eicos">EiCOS</a> <code>-DENABLE_EICOS=TRUE</code>. MIT License.</li>
</ul>
<h2><a class="anchor" id="autotoc_md5"></a>
Usage</h2>
<h3><a class="anchor" id="autotoc_md6"></a>
Download</h3>
<div class="fragment"><div class="line">git clone --recurse-submodules https://github.com/EmbersArc/Epigraph</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md7"></a>
CMake</h3>
<p>To use Epigraph with a cmake project, simply enable the desired solvers, include the subdirectory and link the library. </p><div class="fragment"><div class="line">set(ENABLE_OSQP TRUE)</div>
<div class="line">set(ENABLE_ECOS TRUE)</div>
<div class="line">set(ENABLE_EICOS TRUE)</div>
<div class="line">add_subdirectory(Epigraph)</div>
<div class="line">target_link_libraries(my_library epigraph)</div>
</div><!-- fragment --><h3><a class="anchor" id="autotoc_md8"></a>
Documentation</h3>
<p>While the example below is likely enough to get you started, the full documentation can be found <a href="https://embersarc.github.io/Epigraph/">here</a>.</p>
<h3><a class="anchor" id="autotoc_md9"></a>
Example</h3>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="epigraph_8hpp.html">epigraph.hpp</a>&quot;</span></div>
<div class="line"> </div>
<div class="line"><span class="preprocessor">#include &lt;fmt/format.h&gt;</span></div>
<div class="line"><span class="preprocessor">#include &lt;fmt/ostream.h&gt;</span></div>
<div class="line"> </div>
<div class="line"><span class="comment">// This example solves the portfolio optimization problem in QP form</span></div>
<div class="line"> </div>
<div class="line"><span class="keyword">using namespace </span>cvx;</div>
<div class="line"> </div>
<div class="line"><span class="keywordtype">int</span> main()</div>
<div class="line">{</div>
<div class="line">    <span class="keywordtype">size_t</span> n = 5; <span class="comment">// Assets</span></div>
<div class="line">    <span class="keywordtype">size_t</span> m = 2; <span class="comment">// Factors</span></div>
<div class="line"> </div>
<div class="line">    fmt::print(<span class="stringliteral">&quot;Running with assets: {}, factors: {}\n&quot;</span>, n, m);</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Set up problem data.</span></div>
<div class="line">    <span class="keywordtype">double</span> gamma = 0.5;          <span class="comment">// risk aversion parameter</span></div>
<div class="line">    Eigen::VectorXd mu(n);       <span class="comment">// vector of expected returns</span></div>
<div class="line">    Eigen::MatrixXd F(n, m);     <span class="comment">// factor-loading matrix</span></div>
<div class="line">    Eigen::VectorXd D(n);        <span class="comment">// diagonal of idiosyncratic risk</span></div>
<div class="line">    Eigen::MatrixXd Sigma(n, n); <span class="comment">// asset return covariance</span></div>
<div class="line"> </div>
<div class="line">    mu.setRandom();</div>
<div class="line">    F.setRandom();</div>
<div class="line">    D.setRandom();</div>
<div class="line"> </div>
<div class="line">    mu = mu.cwiseAbs();</div>
<div class="line">    F = F.cwiseAbs();</div>
<div class="line">    D = D.cwiseAbs();</div>
<div class="line">    Sigma = F * F.transpose();</div>
<div class="line">    Sigma.diagonal() += D;</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Formulate QP.</span></div>
<div class="line">    <a class="code" href="classcvx_1_1OptimizationProblem.html">OptimizationProblem</a> qp;</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Declare variables with...</span></div>
<div class="line">    <span class="comment">// addVariable(name) for scalars,</span></div>
<div class="line">    <span class="comment">// addVariable(name, rows) for vectors and</span></div>
<div class="line">    <span class="comment">// addVariable(name, rows, cols) for matrices.</span></div>
<div class="line">    VectorX x = op.<a class="code" href="classcvx_1_1OptimizationProblem.html#abfe91b330b443ac84cfd587063aa244f">addVariable</a>(<span class="stringliteral">&quot;x&quot;</span>, n);</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Available constraint types are equalTo(), lessThan(), greaterThan() and box()</span></div>
<div class="line">    qp.<a class="code" href="classcvx_1_1OptimizationProblem.html#af0320ee7149f1e0e28e8427fa6b316f7">addConstraint</a>(<a class="code" href="constraint_8hpp.html#acdc34f6fa683a0f38f352295dad8981f">greaterThan</a>(x, 0.));</div>
<div class="line">    qp.<a class="code" href="classcvx_1_1OptimizationProblem.html#af0320ee7149f1e0e28e8427fa6b316f7">addConstraint</a>(<a class="code" href="constraint_8hpp.html#a19ae6dab85befb1637b466555a80dbe1">equalTo</a>(x.sum(), 1.));</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Make mu dynamic in the cost function so we can change it later</span></div>
<div class="line">    qp.<a class="code" href="classcvx_1_1OptimizationProblem.html#a75c10fd63c47fffe804f7d3aae574eb5">addCostTerm</a>(x.transpose() * <a class="code" href="expressions_8hpp.html#a684fad62c2a1797e47da4d39361892db">par</a>(gamma * Sigma) * x - <a class="code" href="expressions_8hpp.html#a1d984e3625f4b93568f4d23ae1545706">dynpar</a>(mu).dot(x));</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Print the problem formulation for inspection</span></div>
<div class="line">    fmt::print(<span class="stringliteral">&quot;{}\n&quot;</span>, qp);</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Create and initialize the solver instance.</span></div>
<div class="line">    <a class="code" href="classcvx_1_1osqp_1_1OSQPSolver.html">osqp::OSQPSolver</a> solver(qp);</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Print the canonical problem formulation for inspection</span></div>
<div class="line">    fmt::print(<span class="stringliteral">&quot;{}\n&quot;</span>, solver);</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Solve problem and show solver output</span></div>
<div class="line">    solver.solve(<span class="keyword">true</span>);</div>
<div class="line"> </div>
<div class="line">    fmt::print(<span class="stringliteral">&quot;Solver result: {} ({})\n&quot;</span>, solver.getResultString(), solver.getExitCode());</div>
<div class="line">    <span class="comment">// Call eval() to get the variable values</span></div>
<div class="line">    fmt::print(<span class="stringliteral">&quot;Solution 1:\n {}\n&quot;</span>, <a class="code" href="expressions_8hpp.html#a11d5ec90b597ad187a911b85516205e6">eval</a>(x));</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Update data</span></div>
<div class="line">    mu.setRandom();</div>
<div class="line">    mu = mu.cwiseAbs();</div>
<div class="line"> </div>
<div class="line">    <span class="comment">// Solve again</span></div>
<div class="line">    <span class="comment">// OSQP will warm start automatically</span></div>
<div class="line">    solver.solve(<span class="keyword">true</span>);</div>
<div class="line"> </div>
<div class="line">    fmt::print(<span class="stringliteral">&quot;Solver result: {} ({})\n&quot;</span>, solver.getResultString(), solver.getExitCode());</div>
<div class="line">    fmt::print(<span class="stringliteral">&quot;Solution 2:\n {}\n&quot;</span>, <a class="code" href="expressions_8hpp.html#a11d5ec90b597ad187a911b85516205e6">eval</a>(x));</div>
<div class="line">}</div>
</div><!-- fragment --><p>See the [tests](tests) for more examples, including the same problem in SOCP form.</p>
<h3><a class="anchor" id="autotoc_md10"></a>
Problem Formulation</h3>
<p>The following terms may be passed to the constraint functions:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Function </th><th class="markdownTableHeadNone">Allowed expressions  </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code><a class="el" href="constraint_8hpp.html#a19ae6dab85befb1637b466555a80dbe1" title="Create an equality constraint: lhs == rhs.">equalTo()</a></code> </td><td class="markdownTableBodyNone"><code>Affine == Affine</code>  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><code><a class="el" href="constraint_8hpp.html#ab66996674d0127fea7f2615269365fe8" title="Create a less than or equal constraint: lhs &lt;= rhs.">lessThan()</a></code> </td><td class="markdownTableBodyNone"><code>Affine &lt;= Affine</code> or <code>Norm2 + Affine &lt;= Affine</code> (SOCP)  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code><a class="el" href="constraint_8hpp.html#acdc34f6fa683a0f38f352295dad8981f" title="Create a greater than or equal constraint: lhs &gt;= rhs.">greaterThan()</a></code> </td><td class="markdownTableBodyNone"><code>Affine &gt;= Affine</code> or <code>Affine &gt;= Norm2 + Affine</code> (SOCP)  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><code><a class="el" href="constraint_8hpp.html#ac6ea445abc1a5f95514d8a67ba28ad65" title="Create a box constraint: lower &lt;= middle &lt;= upper.">box()</a></code> </td><td class="markdownTableBodyNone"><code>Affine &lt;= Affine &lt;= Affine</code>  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>addCostTerm()</code> </td><td class="markdownTableBodyNone"><code>Affine</code> (SOCP) or <code>QuadForm + Affine</code> (QP)  </td></tr>
</table>
<p>With the following expressions:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">Expression </th><th class="markdownTableHeadNone">Form  </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>Affine</code> </td><td class="markdownTableBodyNone"><code>p1 * x1 + p2 * x2 + ... + c</code>  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone"><code>Norm2</code> </td><td class="markdownTableBodyNone"><code>(Affine1^2 + Affine2^2 + ...)^(1/2)</code>  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone"><code>QuadForm</code> </td><td class="markdownTableBodyNone"><code>x' * P * x</code> where <code>P</code> is Hermitian  </td></tr>
</table>
</div></div><!-- PageDoc -->
</div><!-- contents -->
<div class="ttc" id="aclasscvx_1_1osqp_1_1OSQPSolver_html"><div class="ttname"><a href="classcvx_1_1osqp_1_1OSQPSolver.html">cvx::osqp::OSQPSolver</a></div><div class="ttdef"><b>Definition:</b> osqpWrapper.hpp:11</div></div>
<div class="ttc" id="aconstraint_8hpp_html_acdc34f6fa683a0f38f352295dad8981f"><div class="ttname"><a href="constraint_8hpp.html#acdc34f6fa683a0f38f352295dad8981f">cvx::greaterThan</a></div><div class="ttdeci">Constraint greaterThan(const Scalar &amp;lhs, const Scalar &amp;rhs)</div><div class="ttdoc">Create a greater than or equal constraint: lhs &gt;= rhs.</div></div>
<div class="ttc" id="aexpressions_8hpp_html_a684fad62c2a1797e47da4d39361892db"><div class="ttname"><a href="expressions_8hpp.html#a684fad62c2a1797e47da4d39361892db">cvx::par</a></div><div class="ttdeci">Scalar par(double p)</div><div class="ttdoc">Creates a constant parameter.</div></div>
<div class="ttc" id="aconstraint_8hpp_html_a19ae6dab85befb1637b466555a80dbe1"><div class="ttname"><a href="constraint_8hpp.html#a19ae6dab85befb1637b466555a80dbe1">cvx::equalTo</a></div><div class="ttdeci">Constraint equalTo(const Scalar &amp;lhs, const Scalar &amp;rhs)</div><div class="ttdoc">Create an equality constraint: lhs == rhs.</div></div>
<div class="ttc" id="aexpressions_8hpp_html_a1d984e3625f4b93568f4d23ae1545706"><div class="ttname"><a href="expressions_8hpp.html#a1d984e3625f4b93568f4d23ae1545706">cvx::dynpar</a></div><div class="ttdeci">Scalar dynpar(double &amp;p)</div><div class="ttdoc">Creates a dynamic parameter.</div></div>
<div class="ttc" id="aclasscvx_1_1OptimizationProblem_html"><div class="ttname"><a href="classcvx_1_1OptimizationProblem.html">cvx::OptimizationProblem</a></div><div class="ttdef"><b>Definition:</b> problem.hpp:16</div></div>
<div class="ttc" id="aexpressions_8hpp_html_a11d5ec90b597ad187a911b85516205e6"><div class="ttname"><a href="expressions_8hpp.html#a11d5ec90b597ad187a911b85516205e6">cvx::eval</a></div><div class="ttdeci">double eval(const Scalar &amp;s)</div><div class="ttdoc">Evaluates the scalar.</div></div>
<div class="ttc" id="aclasscvx_1_1OptimizationProblem_html_a75c10fd63c47fffe804f7d3aae574eb5"><div class="ttname"><a href="classcvx_1_1OptimizationProblem.html#a75c10fd63c47fffe804f7d3aae574eb5">cvx::OptimizationProblem::addCostTerm</a></div><div class="ttdeci">void addCostTerm(const Scalar &amp;term)</div><div class="ttdoc">Add a cost term to the problem's cost function. This has to be a scalar.</div></div>
<div class="ttc" id="aclasscvx_1_1OptimizationProblem_html_af0320ee7149f1e0e28e8427fa6b316f7"><div class="ttname"><a href="classcvx_1_1OptimizationProblem.html#af0320ee7149f1e0e28e8427fa6b316f7">cvx::OptimizationProblem::addConstraint</a></div><div class="ttdeci">void addConstraint(const Constraint &amp;constraint)</div><div class="ttdoc">Add a single constraint to the problem. found.</div></div>
<div class="ttc" id="aclasscvx_1_1OptimizationProblem_html_abfe91b330b443ac84cfd587063aa244f"><div class="ttname"><a href="classcvx_1_1OptimizationProblem.html#abfe91b330b443ac84cfd587063aa244f">cvx::OptimizationProblem::addVariable</a></div><div class="ttdeci">Scalar addVariable(const std::string &amp;name)</div><div class="ttdoc">Creates and returns a variable.</div></div>
<div class="ttc" id="aepigraph_8hpp_html"><div class="ttname"><a href="epigraph_8hpp.html">epigraph.hpp</a></div><div class="ttdoc">The Epigraph library. Enabled solvers will be included here.</div></div>
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.18
</small></address>
</body>
</html>
